﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GUIServerConnectorAPI;
using EntityModel;
using ApplicationConfiguration;

namespace GUIServerConnector
{
    public class ManagerInterface : MarshalByRefObject, IManagerInterface
    {
        private TeleasistentaEntities entities;

        public ManagerInterface()
        {
            entities = new TeleasistentaEntities(AppConfiguration.getInstance().getProperty("Database", "connectionString"));
        }

        private Sesiune getActiveSession(Guid sessionId)
        {
            Sesiune session = entities.Sesiunes.FirstOrDefault(s => s.idSesiune.Equals(sessionId));
            if (session == null)
                throw new AuthenticationException(Strings.InvalidSessionID);
            if (session.Stop_sesiune != null)
                throw new AuthenticationException(Strings.SessionExpired);
            return session;
        }

        private AccountType getAccountType(Sesiune session)
        {
            User user = entities.Users.FirstOrDefault(u => u.idUser == session.idUser);
            if (user == null)
                throw new AuthorizationException(Strings.InvalidSessionUserID);
            return (AccountType)Enum.Parse(typeof(AccountType), user.Rol);
        }

        public void addPacient(Guid sessionId, Pacient pacient)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Pacients.AddObject(pacient);
                entities.SaveChanges();
            }
            else
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
        }

        public void updatePacient(Guid sessionId, Pacient pacient)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Pacients.DeleteObject(entities.Pacients.Single(p => p.idPacient == pacient.idPacient));
                entities.Pacients.AddObject(pacient);
                entities.SaveChanges();
            }
            else
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
        }

        public void removePacient(Guid sessionId, Guid pacientId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Pacients.DeleteObject(entities.Pacients.Single(p => p.idPacient == pacientId));
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public List<Pacient> getPacients(Guid sessionId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                List<Pacient> pacients = new List<Pacient>();
                foreach (Pacient pacient in entities.Pacients)
                {
                    pacients.Add(pacient);
                }
                return pacients;
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public Pacient getPacient(Guid sessionId, Guid pacientId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                return entities.Pacients.SingleOrDefault(p => p.idPacient == pacientId);
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void addIngrijitor(Guid sessionId, Ingrijitor ingrijitor)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Ingrijitors.AddObject(ingrijitor);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void updateIngrijitor(Guid sessionId, Ingrijitor ingrijitor)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Ingrijitors.DeleteObject(entities.Ingrijitors.Single(i => i.idIngrijitor == ingrijitor.idIngrijitor));
                entities.Ingrijitors.AddObject(ingrijitor);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void removeIngrijitor(Guid sessionId, Guid ingrijitorId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Ingrijitors.DeleteObject(entities.Ingrijitors.Single(i => i.idIngrijitor == ingrijitorId));
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public List<Ingrijitor> getIngrijitors(Guid sessionId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                List<Ingrijitor> ingrijitors = new List<Ingrijitor>();
                foreach (Ingrijitor ingrijitor in entities.Ingrijitors)
                {
                    ingrijitors.Add(ingrijitor);
                }
                return ingrijitors;
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public Ingrijitor getIngrijitor(Guid sessionId, Guid ingrijitorId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                return entities.Ingrijitors.SingleOrDefault(i => i.idIngrijitor == ingrijitorId);
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void addSupraveghetor(Guid sessionId, Supraveghetor supraveghetor)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Supraveghetors.AddObject(supraveghetor);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void updateSupraveghetor(Guid sessionId, Supraveghetor supraveghetor)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Supraveghetors.DeleteObject(entities.Supraveghetors.Single(s => s.idSupraveghetor == supraveghetor.idSupraveghetor));
                entities.Supraveghetors.AddObject(supraveghetor);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void removeSupraveghetor(Guid sessionId, Guid supraveghetorId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Supraveghetors.DeleteObject(entities.Supraveghetors.Single(s => s.idSupraveghetor == supraveghetorId));
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public List<Supraveghetor> getSupraveghetors(Guid sessionId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                List<Supraveghetor> supraveghetors = new List<Supraveghetor>();
                foreach (Supraveghetor supraveghetor in entities.Supraveghetors)
                {
                    supraveghetors.Add(supraveghetor);
                }
                return supraveghetors;
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public Supraveghetor getSupraveghetor(Guid sessionId, Guid supraveghetorId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                return entities.Supraveghetors.SingleOrDefault(s => s.idSupraveghetor == supraveghetorId);
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void addMedic(Guid sessionId, Medic medic)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Medics.AddObject(medic);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void updateMedic(Guid sessionId, Medic medic)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Medics.DeleteObject(entities.Medics.Single(m => m.idMedic == medic.idMedic));
                entities.Medics.AddObject(medic);
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public void removeMedic(Guid sessionId, Guid medicId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                entities.Medics.DeleteObject(entities.Medics.Single(m => m.idMedic == medicId));
                entities.SaveChanges();
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public List<Medic> getMedics(Guid sessionId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                List<Medic> medics = new List<Medic>();
                foreach (Medic medic in entities.Medics)
                {
                    medics.Add(medic);
                }
                return medics;
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

        public Medic getMedic(Guid sessionId, Guid medicId)
        {
            Sesiune activeSession = getActiveSession(sessionId);
            AccountType accountType = getAccountType(activeSession);
            if (accountType.Equals(AccountType.MANAGER))
            {
                return entities.Medics.SingleOrDefault(m => m.idMedic == medicId);
            }
            else
            {
                throw new AuthorizationException(Strings.OperationInvalidForAccountType);
            }
        }

    }
}
